package jp.co.hcs.attendancemanagement.inputdailyattendance.logic;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import jp.co.hcs.attendancemanagement.StrutsMessageConstants;
import jp.co.hcs.attendancemanagement.data.dao.EffortActualDAO;
import jp.co.hcs.attendancemanagement.data.dao.EmployeeMasterDAO;
import jp.co.hcs.attendancemanagement.data.dao.EmployeeVacationDAO;
import jp.co.hcs.attendancemanagement.data.dao.JobDAO;
import jp.co.hcs.attendancemanagement.data.dao.PerformanceStampDAO;
import jp.co.hcs.attendancemanagement.data.dao.PositionMasterDAO;
import jp.co.hcs.attendancemanagement.data.dao.ProjectDAO;
import jp.co.hcs.attendancemanagement.data.dao.RestTimeActualDAO;
import jp.co.hcs.attendancemanagement.data.dao.RestTimeDAO;
import jp.co.hcs.attendancemanagement.data.dao.SubstituteHolidayActualDAO;
import jp.co.hcs.attendancemanagement.data.dao.WorkDAO;
import jp.co.hcs.attendancemanagement.data.dao.WorkMessageDAO;
import jp.co.hcs.attendancemanagement.data.dao.WorkingTimeActualDAO;
import jp.co.hcs.attendancemanagement.data.dao.WorkingTimeMasterDAO;
import jp.co.hcs.attendancemanagement.data.entity.Project;
import jp.co.hcs.attendancemanagement.data.entity.Work;
import jp.co.hcs.attendancemanagement.data.entity.WorkingTimeActual;
import jp.co.hcs.attendancemanagement.data.entity.WorkingTimeMaster;
import jp.co.hcs.attendancemanagement.exception.AMSQLException;
import jp.co.hcs.attendancemanagement.inputdailyattendance.logic.dto.DailyWorkingActualResultDTO;
import jp.co.hcs.attendancemanagement.logic.LogicBase;
import jp.co.hcs.attendancemanagement.util.DateUtil;
import jp.co.hcs.attendancemanagement.util.StringUtil;
import jp.co.hcs.attendancemanagement.util.TimeUtil;

public class InputDailyWorkingLogicBase extends LogicBase {

    /** The employee master dao. */
    private EmployeeMasterDAO employeeMasterDAO;

    /** The working time actual dao. */
    private WorkingTimeActualDAO workingTimeActualDAO;

    /** The performance stamp dao. */
    private PerformanceStampDAO performanceStampDAO;

    /** The effort actual dao. */
    private EffortActualDAO effortActualDAO;

    /** The substitute holiday actual dao. */
    private SubstituteHolidayActualDAO substituteHolidayActualDAO;

    /** The rest time actual dao. */
    private RestTimeActualDAO restTimeActualDAO;

    /** The employee vacation dao. */
    private EmployeeVacationDAO employeeVacationDAO;

    /** The rest time dao. */
    private RestTimeDAO restTimeDAO;

    /** The job dao. */
    private JobDAO jobDAO;

    /** The position master dao. */
    private PositionMasterDAO positionMasterDAO;

    /** The working time master dao. */
    private WorkingTimeMasterDAO workingTimeMasterDAO;

    /** The work dao. */
    private WorkDAO workDAO;

    /** The project dao. */
    private ProjectDAO projectDAO;

    /** The work message dao. */
    private WorkMessageDAO workMessageDAO;

    /**
     * Gets the employee master dao.
     * 
     * @return the employee master dao
     */
    protected EmployeeMasterDAO getEmployeeMasterDAO() {
        if (employeeMasterDAO == null) {
            employeeMasterDAO = daoFactory.getEmployeeMasterDAO();
        }
        return employeeMasterDAO;
    }

    /**
     * Gets the working time actual dao.
     * 
     * @return the working time actual dao
     */
    protected WorkingTimeActualDAO getWorkingTimeActualDAO() {
        if (workingTimeActualDAO == null) {
            workingTimeActualDAO = daoFactory.getWorkingTimeActualDAO();
        }
        return workingTimeActualDAO;
    }

    /**
     * Gets the performance stamp dao.
     * 
     * @return the performance stamp dao
     */
    protected PerformanceStampDAO getPerformanceStampDAO() {
        if (performanceStampDAO == null) {
            performanceStampDAO = daoFactory.getPerformanceStampDAO();
        }
        return performanceStampDAO;
    }

    /**
     * Gets the effort actual dao.
     * 
     * @return the effort actual dao
     */
    protected EffortActualDAO getEffortActualDAO() {
        if (effortActualDAO == null) {
            effortActualDAO = daoFactory.getEffortActualDAO();
        }
        return effortActualDAO;
    }

    /**
     * Gets the substitute holiday actual dao.
     * 
     * @return the substitute holiday actual dao
     */
    protected SubstituteHolidayActualDAO getSubstituteHolidayActualDAO() {
        if (substituteHolidayActualDAO == null) {
            substituteHolidayActualDAO = daoFactory
                    .getSubstituteHolidayActualDAO();
        }
        return substituteHolidayActualDAO;
    }

    /**
     * Gets the rest time actual dao.
     * 
     * @return the rest time actual dao
     */
    protected RestTimeActualDAO getRestTimeActualDAO() {
        if (restTimeActualDAO == null) {
            restTimeActualDAO = daoFactory.getRestTimeActualDAO();
        }
        return restTimeActualDAO;
    }

    /**
     * Gets the employee vacation dao.
     * 
     * @return the employee vacation dao
     */
    protected EmployeeVacationDAO getEmployeeVacationDAO() {
        if (employeeVacationDAO == null) {
            employeeVacationDAO = daoFactory.getEmployeeVacationDAO();
        }
        return employeeVacationDAO;
    }

    /**
     * Gets the rest time dao.
     * 
     * @return the rest time dao
     */
    protected RestTimeDAO getRestTimeDAO() {
        if (restTimeDAO == null) {
            restTimeDAO = daoFactory.getRestTimeDAO();
        }
        return restTimeDAO;
    }

    /**
     * Gets the job dao.
     * 
     * @return the job dao
     */
    protected JobDAO getJobDAO() {
        if (jobDAO == null) {
            jobDAO = daoFactory.getJobDivisionDAO();
        }
        return jobDAO;
    }

    /**
     * Gets the position master dao.
     * 
     * @return the position master dao
     */
    protected PositionMasterDAO getPositionMasterDAO() {
        if (positionMasterDAO == null) {
            positionMasterDAO = daoFactory.getPositionMasterDAO();
        }
        return positionMasterDAO;
    }

    /**
     * Gets the working time master dao.
     * 
     * @return the working time master dao
     */
    protected WorkingTimeMasterDAO getWorkingTimeMasterDAO() {
        if (workingTimeMasterDAO == null) {
            workingTimeMasterDAO = daoFactory.getWorkingTimeMasterDAO();
        }
        return workingTimeMasterDAO;
    }

    /**
     * Gets the work dao.
     * 
     * @return the work dao
     */
    protected WorkDAO getWorkDAO() {
        if (workDAO == null) {
            workDAO = daoFactory.getWorkDAO();
        }
        return workDAO;
    }

    /**
     * Gets the project dao.
     * 
     * @return the project dao
     */
    protected ProjectDAO getProjectDAO() {
        if (projectDAO == null) {
            projectDAO = daoFactory.getProjectDAO();
        }
        return projectDAO;
    }

    /**
     * Gets the work message dao.
     * 
     * @return the work message dao
     */
    protected WorkMessageDAO getWorkMessageDAO() {
        if (workMessageDAO == null) {
            workMessageDAO = daoFactory.getWorkMessageDAO();
        }
        return workMessageDAO;
    }
    
    /**
     * Check project code.
     * 
     * @param projectCode
     *            the project code
     * @param seri
     *            the seri
     * @param errors
     *            the errors
     * @return the string
     * @throws SQLException
     *             the sQL exception
     */
    protected String checkProjectCode(String projectCode, String seri,
            ActionMessages errors) throws SQLException {
        Project project = getProjectDAO().selectProjectByPrimaryKey(
                projectCode + seri);

        if (project == null) {
            errors.add(ActionErrors.GLOBAL_MESSAGE, new ActionMessage(
                    StrutsMessageConstants.ALARM_W1058_ERROR, projectCode));
            return null;
        }

        String status = project.getStatus();
        if ("1".equals(status) || "2".equals(status) || "3".equals(status)) {
            return project.getProjectName();
        } else {
            errors.add(ActionErrors.GLOBAL_MESSAGE, new ActionMessage(
                    StrutsMessageConstants.ALARM_W1059_ERROR, projectCode));
            return null;
        }
    }

    /**
     * Check work code.
     * 
     * @param workCode
     *            the work code
     * @param errors
     *            the errors
     * @return the string
     * @throws SQLException
     *             the sQL exception
     */
    protected String checkWorkCode(String workCode, ActionMessages errors)
            throws SQLException {
        Work work = getWorkDAO().selectWorkByPrimaryKey(workCode);

        if (work == null) {
            errors.add(ActionErrors.GLOBAL_MESSAGE, new ActionMessage(
                    StrutsMessageConstants.ALARM_W1060_ERROR, workCode));
            return null;
        }

        return work.getWorkName();
    }
    
    /**
     * Copy properties daily working.
     * 
     * @param dailyWorking the daily working
     * @param workingTimeActual the working time actual
     * @param year the year
     */
    protected void copyPropertiesDailyWorking(DailyWorkingActualResultDTO dailyWorking,
        WorkingTimeActual workingTimeActual, String year) {
      workingTimeActual.setApprovalStatus(dailyWorking.getDailyWorkingApprovalStatus());
      workingTimeActual.setWorkingPlannedStartTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getPlannedWorkingStartTime()));
      workingTimeActual.setWorkingPlannedEndTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getPlannedWorkingEndTime()));
      workingTimeActual.setJobId(dailyWorking.getJobDivision());
      if (!StringUtil.isEmpty(dailyWorking.getWorkingStartTime())) {
        workingTimeActual.setWorkingStartTime(DateUtil.parseDateFromHHmm(dailyWorking.getWorkingStartTime()));
      } else {
        workingTimeActual.setWorkingStartTime(null);
      }
      if (!StringUtil.isEmpty(dailyWorking.getWorkingStartDay())) {
        workingTimeActual.setWorkingStartDay(DateUtil.parseDate(dailyWorking.getWorkingStartDay(), year));
      } else {
        workingTimeActual.setWorkingStartDay(null);
      }
      if (!StringUtil.isEmpty(dailyWorking.getWorkingEndDay())) {
        workingTimeActual.setWorkingEndDay(DateUtil.parseDate(dailyWorking.getWorkingEndDay(), year));
      } else {
        workingTimeActual.setWorkingEndDay(null);
      }
      if (!StringUtil.isEmpty(dailyWorking.getWorkingEndTime())) {
        workingTimeActual.setWorkingEndTime(DateUtil.parseDateFromHHmm(dailyWorking.getWorkingEndTime()));
      } else {
        workingTimeActual.setWorkingEndTime(null);
      }
      workingTimeActual.setTimeType(dailyWorking.getTimeDivision());
      workingTimeActual.setApplicationNo(dailyWorking.getApplicationNo());
      workingTimeActual.setAdditionalHolidayNo(dailyWorking.getSubstituteHolidayNo());
      workingTimeActual.setTakingVacationNo(dailyWorking.getTakingVacationNo());
      workingTimeActual.setPaidHoliday(DateUtil.parseDateFromHHmm(dailyWorking.getPaidHoliday()));
      workingTimeActual.setWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking.getWorkingTime()));
      workingTimeActual.setWorkingPlannedTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getPlannedWorkingTime()));
      workingTimeActual.setOvertimeAutomaticApply(DateUtil.parseDateFromHHmm(dailyWorking
          .getOvertimeAutomaticApply()));
      workingTimeActual.setIsComingLate(dailyWorking.getComingLateFlag());
      workingTimeActual.setIsReturningEarly(dailyWorking.getLeavingEarlyFlag());
      workingTimeActual.setIsCommutingDelay(dailyWorking.getCommutingDelayFlag());
      workingTimeActual.setRestTime(DateUtil.parseDateFromHHmm(dailyWorking.getRestTime()));
      workingTimeActual.setComment(dailyWorking.getComment());
      workingTimeActual.setWorkingFixTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getFixedWorkingTime()));
      workingTimeActual.setOvertimeTime(DateUtil.parseDateFromHHmm(dailyWorking.getOvertime()));
      workingTimeActual.setNightWorkTime(DateUtil.parseDateFromHHmm(dailyWorking.getNightWorkTime()));
      workingTimeActual.setSaturdayWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getSatWorkingTime()));
      workingTimeActual.setSundayAndHolidayWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getHolidayWorkTime()));
      workingTimeActual.setSubstituteHolidayWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getSubstituteHolidayTime()));
      workingTimeActual.setInsufficentWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getInsufficentTime()));
      workingTimeActual.setSaturdayMidnightWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getSatNightWorkTime()));
      workingTimeActual.setSundayAndHolidayMidnightWorkingTime(DateUtil
          .parseDateFromHHmm(dailyWorking.getHolidayNightWorkTime()));
      workingTimeActual.setAnnouncement(dailyWorking.getAnnouncement());
      workingTimeActual.setAdditionalHolidayNo(dailyWorking.getAddedSubstituteHolidayNo());
      workingTimeActual.setTotalOvertimePerDay(DateUtil.parseDateFromHHmm(dailyWorking
          .getTotalOvertimePerDay()));
      workingTimeActual.setMidnightShiftWorkingTime(DateUtil.parseDateFromHHmm(dailyWorking
          .getNightShiftWork()));
    }
    
    /**
     * Round working time info.
     * 
     * @param dailyWorking the daily working
     * @throws SQLException the sQL exception
     * @throws AMSQLException 
     */
    protected void roundWorkingTimeInfo(DailyWorkingActualResultDTO dailyWorking) throws SQLException, AMSQLException {
      WorkingTimeMaster workingTimeMaster =
          getWorkingTimeMasterDAO().selectWorkingTimeMasterByPrimaryKey(
              dailyWorking.getTimeDivision());

      if (workingTimeMaster.getRoundTime() == null || workingTimeMaster.getRoundTime() == 0) {
        throw new AMSQLException("Round time is not defined");
      }
      
      // rounding working time info
      int roundingTime = workingTimeMaster.getRoundTime();

      String overtime = dailyWorking.getOvertime();
      if (!TimeUtil.isTimeEmpty(overtime)) {
        overtime = TimeUtil.roundTime(overtime, roundingTime);
        overtime = StringUtil.fullWidthNumberToHalfWidthNumber(overtime);
        dailyWorking.setOvertime(overtime);
      }

      String nightWorkTime = dailyWorking.getNightWorkTime();
      if (!TimeUtil.isTimeEmpty(nightWorkTime)) {
        nightWorkTime = TimeUtil.roundTime(nightWorkTime, roundingTime);
        nightWorkTime = StringUtil.fullWidthNumberToHalfWidthNumber(nightWorkTime);
        dailyWorking.setNightWorkTime(nightWorkTime);
      }

      String substituteHolidayTime = dailyWorking.getSubstituteHolidayTime();
      if (!TimeUtil.isTimeEmpty(substituteHolidayTime)) {
        substituteHolidayTime = TimeUtil.roundTime(substituteHolidayTime, roundingTime);
        substituteHolidayTime = StringUtil.fullWidthNumberToHalfWidthNumber(substituteHolidayTime);
        dailyWorking.setSubstituteHolidayTime(substituteHolidayTime);
      }

      String saturdayWorkTime = dailyWorking.getSatWorkingTime();
      if (!TimeUtil.isTimeEmpty(saturdayWorkTime)) {
        saturdayWorkTime = TimeUtil.roundTime(saturdayWorkTime, roundingTime);
        saturdayWorkTime = StringUtil.fullWidthNumberToHalfWidthNumber(saturdayWorkTime);
        dailyWorking.setSatWorkingTime(saturdayWorkTime);
      }

      String saturdayNightWorkTime = dailyWorking.getSatNightWorkTime();
      if (!TimeUtil.isTimeEmpty(saturdayNightWorkTime)) {
        saturdayNightWorkTime = TimeUtil.roundTime(saturdayNightWorkTime, roundingTime);
        saturdayNightWorkTime = StringUtil.fullWidthNumberToHalfWidthNumber(saturdayNightWorkTime);
        dailyWorking.setSatNightWorkTime(saturdayNightWorkTime);
      }

      String nightShiftWorkTime = dailyWorking.getNightShiftWork();
      if (!TimeUtil.isTimeEmpty(nightShiftWorkTime)) {
        nightShiftWorkTime = TimeUtil.roundTime(nightShiftWorkTime, roundingTime);
        nightShiftWorkTime = StringUtil.fullWidthNumberToHalfWidthNumber(nightShiftWorkTime);
        dailyWorking.setNightShiftWork(nightShiftWorkTime);
      }

      String holidayWorkTime = dailyWorking.getHolidayWorkTime();
      if (!TimeUtil.isTimeEmpty(holidayWorkTime)) {
        holidayWorkTime = TimeUtil.roundTime(holidayWorkTime, roundingTime);
        holidayWorkTime = StringUtil.fullWidthNumberToHalfWidthNumber(holidayWorkTime);
        dailyWorking.setHolidayWorkTime(holidayWorkTime);
      }

      String holidayNightWorkTime = dailyWorking.getHolidayNightWorkTime();
      if (!TimeUtil.isTimeEmpty(holidayNightWorkTime)) {
        holidayNightWorkTime = TimeUtil.roundTime(holidayNightWorkTime, roundingTime);
        holidayNightWorkTime = StringUtil.fullWidthNumberToHalfWidthNumber(holidayNightWorkTime);
        dailyWorking.setHolidayNightWorkTime(holidayNightWorkTime);
      }
    }
    
    protected String calculateDailyOvertimeTotal(DailyWorkingActualResultDTO dailyWorking) {
        List<String> dailyOvertimeList = new ArrayList<String>();
        dailyOvertimeList.add(dailyWorking.getOvertime());
        dailyOvertimeList.add(dailyWorking.getNightWorkTime());
        dailyOvertimeList.add(dailyWorking.getSatWorkingTime());
        dailyOvertimeList.add(dailyWorking.getSatNightWorkTime());
        dailyOvertimeList.add(dailyWorking.getHolidayWorkTime());
        dailyOvertimeList.add(dailyWorking.getHolidayNightWorkTime());
        return TimeUtil.calculateTotalTime(dailyOvertimeList);
    }
    
    protected String calculateSpecialOvertime(DailyWorkingActualResultDTO dailyWorking) {
        List<String> specialOvertimeList = new ArrayList<String>();
        specialOvertimeList.add(dailyWorking.getOvertime());
        specialOvertimeList.add(dailyWorking.getNightWorkTime());
        specialOvertimeList.add(dailyWorking.getSatWorkingTime());
        specialOvertimeList.add(dailyWorking.getSatNightWorkTime());
        return TimeUtil.calculateTotalTime(specialOvertimeList);
    }
}
